﻿  using UnityEngine;
using System.Collections;
using System.IO;
using System.Collections.Generic;
using System;
using System.Text;
using System.Xml;
using System.Security.Cryptography;

public class GameDataManager : MonoBehaviour
{
	#region ---------------------------------------------- 定义数据储存类 ----------------------------------------------
	/// <summary>
	/// 所有表的父类 //
	/// Game data.
	/// </summary>
	public class GameData
	{
		public string key;	// 密钥,用于防止拷贝存档 //
	}
	
	/// <summary>
	/// User data.
	/// </summary>
	public class UserData : GameData
	{
		public long wan;	// 相当于钱 //
		
		public UserData()
		{
			key = SystemInfo.deviceUniqueIdentifier;
		}
	}
	
	/// <summary>
	/// 2048的数据 //
	/// Data 2048.
	/// </summary>
	public class _2048Data : GameData
	{
		public string[] bestScoresInEachModel;
		public int[] propsQuantity;	// 道具数量, [0]:后悔药, [1]:交换, [2]:干掉 //
		public string[] historyLayoutsInEachModel; // 每个关卡的历史步骤 //
		public int[] reachGoalScoreTotalTimes;	// 达到过各个高分的总次数, 总共包括7个: 2048--131072 //
		
		public _2048Data()
		{
			key = SystemInfo.deviceUniqueIdentifier;
			
			propsQuantity = new int[3];
			historyLayoutsInEachModel = new string[10];	// !!!!!!!!!!!暂时不知道数量, 需要查 //
			reachGoalScoreTotalTimes = new int[7];
		}
	}

	/// <summary>
	/// 道具数据 //
	/// Props data.
	/// </summary>
	public class PropsData : GameData
	{
		public int[] propsIDs;
		public int[] propsQuantitys;
		
		public PropsData()
		{
			key = SystemInfo.deviceUniqueIdentifier;
		}
	}
	#endregion

	#region ---------------------------------------------- 定义普通成员 ----------------------------------------------
	private string dataFileUserName = "Important0.dat";	// 用户的数据文件名 //
	private string dataFile2048Name = "Important1.dat";	// 2048的数据文件名 //
	
	public UserData userData = new UserData();
	public _2048Data __2048Data = new _2048Data();

	private XmlSaver xs = new XmlSaver();

	public Action saveDatasHandle;	// 需要保存的数据的多播委托 //
	#endregion

	#region ---------------------------------------------- 初始化 ----------------------------------------------
	/// <summary>
	/// 初始化的时候直接添加保存用户数据委托 //
	/// Init the specified initNextHandler and path.
	/// </summary>
	/// <param name="initNextHandler">Init next handler.</param>
	/// <param name="path">Path.</param>
	public void Init(Action initNextHandler)
	{
		StartCoroutine(IEnumeratorInit(initNextHandler));
	}
	
	IEnumerator IEnumeratorInit(Action initNextHandler)
	{
		saveDatasHandle += SaveUserData;

		// 加载用户数据 //
		LoadUserData();

		yield return null;
		
		initNextHandler();
	}
	#endregion

	#region ---------------------------------------------- User(用户)数据相关操作 ----------------------------------------------
	/// <summary>
	/// Saves the user data.
	/// </summary>
	public void SaveUserData()
	{
		string gameDataFile = GetDataPath() + "/" + dataFileUserName;
		string dataString = xs.SerializeObject(userData, typeof(UserData));
		xs.CreateXML(gameDataFile,dataString);
	}
	
	/// <summary>
	/// Loads the user data.
	/// </summary>
	public void LoadUserData()
	{
		string gameDataFile = GetDataPath() + "/" + dataFileUserName;
		if(xs.hasFile(gameDataFile))
		{
			string dataString = xs.LoadXML(gameDataFile);
			UserData gameDataFromXML = xs.DeserializeObject(dataString, typeof(UserData)) as UserData;
			
			// 是合法存档 //
			if(gameDataFromXML.key == userData.key)
			{
				userData = gameDataFromXML;
			}
			// 是非法拷贝存档 //
			else
			{
				// 留空：游戏启动后数据清零，存档后作弊档被自动覆盖 //
			}
		}
		else
		{
			if(userData != null)
			{
				SaveUserData();
			}
		}
	}
	#endregion

	/// <summary>
	/// 设置游戏的时候保存一次数据 //
	/// Raises the application pause event.
	/// </summary>
	/// <param name="pauseStatus">If set to <c>true</c> pause status.</param>
	void OnApplicationPause(bool pauseStatus)
	{
		if(pauseStatus)
		{
			saveDatasHandle();
		}
	}

	/// <summary>
	/// 关闭游戏的时候保存一次数据 //
	/// Raises the application quit event.
	/// </summary>
	void OnApplicationQuit()
	{
		saveDatasHandle();
	}

	#region ---------------------------------------------- 2048(2048)数据相关操作 ----------------------------------------------
	/// <summary>
	/// Save2048s the data.
	/// </summary>
	public void Save2048Data()
	{
		string gameDataFile = GetDataPath() + "/" + dataFile2048Name;
		string dataString = xs.SerializeObject(__2048Data, typeof(_2048Data));
		xs.CreateXML(gameDataFile,dataString);
	}
	
	/// <summary>
	/// Load2048s the data.
	/// </summary>
	public void Load2048Data()
	{
		string gameDataFile = GetDataPath() + "/" + dataFile2048Name;
		if(xs.hasFile(gameDataFile))
		{
			string dataString = xs.LoadXML(gameDataFile);
			_2048Data gameDataFromXML = xs.DeserializeObject(dataString, typeof(_2048Data)) as _2048Data;
			
			// 是合法存档 //
			if(gameDataFromXML.key == __2048Data.key)
			{
				__2048Data = gameDataFromXML;
			}
			// 是非法拷贝存档 //
			else
			{
				// 留空：游戏启动后数据清零，存档后作弊档被自动覆盖 //
			}
		}
		else
		{
			if(__2048Data != null)
			{
				Save2048Data();
			}
		}
	}
	#endregion

	// 获取路径 //
	private static string GetDataPath()
	{
		/*
		// Your game has read+write access to /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/Documents
		// Application.dataPath returns ar/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/myappname.app/Data             
		// Strip "/Data" from path
		if(Application.platform == RuntimePlatform.IPhonePlayer)
		{
			string path = Application.dataPath.Substring (0, Application.dataPath.Length - 5);
			// Strip application name
			path = path.Substring(0, path.LastIndexOf('/')); 
			return path + "/Documents";
		}
		else
			//    return Application.dataPath + "/Resources";
			return Application.dataPath;
		*/
		// 上面为原版风宇冲的做法, 不过实际中貌似路径貌似有点问题,所以修改成下面的做法 //
#if UNITY_EDITOR
		// 为了测试方便, 删除数据文件 //
		return Application.dataPath;
#else
		return Application.persistentDataPath;
#endif
	}

	#region ---------------------------------------------- Singlestone ----------------------------------------------
	private static GameDataManager instance;
	public static GameDataManager Instance
	{
		get
		{
			if (instance == null)
			{
				GameObject go = new GameObject("GameDataManager", typeof(GameDataManager));
				instance = go.GetComponent<GameDataManager>();
				DontDestroyOnLoad(go);
			}
			
			return instance;
		}
	}
	#endregion
}